package com.fsh.lingsp.common.websocket.adapter;

import cn.hutool.core.bean.BeanUtil;
import com.fsh.lingsp.common.chat.domain.dto.ChatMessageMarkDTO;
import com.fsh.lingsp.common.chat.domain.dto.ChatMsgRecallDTO;
import com.fsh.lingsp.common.chat.domain.vo.response.ChatMessageResp;
import com.fsh.lingsp.common.chat.domain.vo.response.msg.ChatMemberStatisticResp;
import com.fsh.lingsp.common.chat.service.ChatService;
import com.fsh.lingsp.common.common.domain.enums.YseOrNoEnum;
import com.fsh.lingsp.common.user.domain.entity.User;
import com.fsh.lingsp.common.user.domain.enums.ChatActiveStatusEnum;
import com.fsh.lingsp.common.websocket.domain.enums.WSRespTypeEnum;
import com.fsh.lingsp.common.websocket.domain.vo.response.*;
import me.chanjar.weixin.mp.bean.result.WxMpQrCodeTicket;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Collections;

@Component
public class WSAdapter {

    @Autowired
    private ChatService chatService;

    /**
     * 构造 WSBaseResp<WSLoginUrl>：
     *      type=1，登录二维码返回
     *      WSLoginUrl信息
     */
    public static WSBaseResp<?> buildLoginResp(WxMpQrCodeTicket wxMpQrCodeTicket) {
        WSBaseResp<WSLoginUrl> resp=new WSBaseResp<>();
        resp.setData(new WSLoginUrl(wxMpQrCodeTicket.getUrl()));
        resp.setType(WSRespTypeEnum.LOGIN_URL.getType());
        return resp;
    }

    /**
     * 构造 WSBaseResp<WSLoginSuccess>：
     *      type=3，用户登录成功返回用户信息
     *      WSLoginSuccess信息
     */
    public static WSBaseResp<?> buildUserResp(User user, String token, boolean power) {
        WSBaseResp<WSLoginSuccess> resp=new WSBaseResp<>();
        resp.setType(WSRespTypeEnum.LOGIN_SUCCESS.getType());
        WSLoginSuccess wsLoginSuccess=WSLoginSuccess.builder()
                .avatar(user.getAvatar())
                .name(user.getName())
                .token(token)
                .uid(user.getId())
                //power。  true就是聊天室管理员(1) ，false就是普通群员(0)
                .power(power? YseOrNoEnum.YES.getStatus():YseOrNoEnum.NO.getStatus())
                .build();
        resp.setData(wsLoginSuccess);
        return resp;
    }

    /**
     * 构造 WSBaseResp<WSLoginUrl>：
     *      type=2，用户扫描成功等待授权
     *      WSLoginUrl信息
     */
    public static WSBaseResp<?> buildWaitAuthorize() {
        WSBaseResp<WSLoginUrl> resp=new WSBaseResp<>();
        resp.setType(WSRespTypeEnum.LOGIN_SCAN_SUCCESS.getType());
        return resp;
    }

    /**
     * 构造 WSBaseResp<WSLoginUrl>：
     *      type=6，使前端的token失效，意味着前端需要重新登录
     *      WSLoginUrl信息不用设置。
     */
    public static WSBaseResp<?> buildInvalidTokenResp() {
        WSBaseResp<WSLoginUrl> resp=new WSBaseResp<>();
        resp.setType(WSRespTypeEnum.INVALIDATE_TOKEN.getType());
        return resp;
    }

    /**
     * 构造 WSBaseResp<WSBlack>：
     *      type=7 , 拉黑用户
     *      WSBlack里存的是 被拉黑用户的uid
     */
    public static WSBaseResp<?> buildBlackResp(User user) {
        WSBaseResp<WSBlack> resp=new WSBaseResp<>();
        resp.setType(WSRespTypeEnum.BLACK.getType());
        resp.setData(new WSBlack(user.getId()));
        return resp;
    }

    public static WSBaseResp<ChatMessageResp> buildMsgSend(ChatMessageResp msgResp) {
        WSBaseResp<ChatMessageResp> wsBaseResp = new WSBaseResp<>();
        wsBaseResp.setType(WSRespTypeEnum.MESSAGE.getType());
        wsBaseResp.setData(msgResp);
        return wsBaseResp;
    }

    /**
     * 构造 WSBaseResp<WSMsgRecall>：
     *      type=9 , 消息撤回
     *      WSMsgRecall 里面是一个 ChatMsgRecallDTO
     */
    public static WSBaseResp<?> buildMsgRecall(ChatMsgRecallDTO recallDTO) {
        WSBaseResp<WSMsgRecall> wsBaseResp = new WSBaseResp<>();
        wsBaseResp.setType(WSRespTypeEnum.RECALL.getType());
        WSMsgRecall recall = new WSMsgRecall();
        BeanUtils.copyProperties(recallDTO, recall);
        wsBaseResp.setData(recall);
        return wsBaseResp;
    }

    public static WSBaseResp<WSMsgMark> buildMsgMarkSend(ChatMessageMarkDTO dto, Integer markCount) {
        WSMsgMark.WSMsgMarkItem item = new WSMsgMark.WSMsgMarkItem();
        BeanUtils.copyProperties(dto, item);
        item.setMarkCount(markCount);
        WSBaseResp<WSMsgMark> wsBaseResp = new WSBaseResp<>();
        wsBaseResp.setType(WSRespTypeEnum.MARK.getType());
        WSMsgMark mark = new WSMsgMark();
        mark.setMarkList(Collections.singletonList(item));
        wsBaseResp.setData(mark);
        return wsBaseResp;
    }

    public WSBaseResp<WSOnlineOfflineNotify>  buildOfflineNotifyResp(User user) {
        WSBaseResp<WSOnlineOfflineNotify> wsBaseResp = new WSBaseResp<>();
        wsBaseResp.setType(WSRespTypeEnum.ONLINE_OFFLINE_NOTIFY.getType());
        WSOnlineOfflineNotify onlineOfflineNotify = new WSOnlineOfflineNotify();
        onlineOfflineNotify.setChangeList(Collections.singletonList(buildOfflineInfo(user)));
        assembleNum(onlineOfflineNotify);
        wsBaseResp.setData(onlineOfflineNotify);
        return wsBaseResp;
    }
    private static ChatMemberResp buildOfflineInfo(User user) {
        ChatMemberResp info = new ChatMemberResp();
        BeanUtil.copyProperties(user, info);
        info.setUid(user.getId());
        info.setActiveStatus(ChatActiveStatusEnum.OFFLINE.getStatus());
        info.setLastOptTime(user.getLastOptTime());
        return info;
    }
    private void assembleNum(WSOnlineOfflineNotify onlineOfflineNotify) {
        ChatMemberStatisticResp memberStatistic = chatService.getMemberStatistic();
        onlineOfflineNotify.setOnlineNum(memberStatistic.getOnlineNum());
    }
}
